package cn.wilson.direct;

import cn.wilson.ConnectionUtil;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 *      消息接受者   消费者
 */
public class Rev2 {
    //队列的名字
    public static final String DIRECT_NAME_2 = "direct_name_2";

    public static void main(String[] args) {

        try (
            //自动关流  jdk新特性
            //使用工具创建连接
            Connection connection = ConnectionUtil.getConnection();
            //使用连接对象，创建通道
            Channel channel = connection.createChannel();
        ){
            //声明队列  他要去队列中取消息，肯定就是生产者的队列
            channel.queueDeclare(
                    DIRECT_NAME_2,      //队列的名字
                    true,       //队列持久化，当你关掉进程，再重启，这个队列还在
                    false,      //一个队列就占一个连接  不要
                    false,      //自动删除  这个队列用完就删了
                    null        //队列的其他属性
            );

            //把队列绑定到交换机
            channel.queueBind(DIRECT_NAME_2, Send.DIRECT_EXCHANGE,DIRECT_NAME_2);

            //能者多劳
            channel.basicQos(1);

            //处理消息的回调   匿名类部类用外面的变量要使用final
            Consumer consumer = new DefaultConsumer(channel){
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                    //模拟异常
//                    int i = 1/0;


                    //消费消息
                    System.out.println("REV2接收的消息内容：" + new String(body));


                    //消息的id
                    long deliveryTag = envelope.getDeliveryTag();
                    // 手动签收
                    channel.basicAck(
                            deliveryTag,    //要签收的消息id
                            false   //签收所有消息  不要
                            );
                }
            };
            //接收消息 --消费消息  这里先执行，拿到结果给回调
            channel.basicConsume(
                    DIRECT_NAME_2, //接收哪个队列的消息，是我们生产者声明的队列
                    false,   //消息的自动签收，主要mq把消息推送到消费者来，mq就直接把消息删掉了
                    consumer        //回调 --真正接收消息是在回调里面接收的
            );

            //消息丢失  ：消费消息和回调是异步执行，当消费消息把结果给回调，程序依然会往下执行，回调还没来得及处理，主进程就结束了
            //让主线程睡会，等回调处理完，主线程再结束
            Thread.sleep(10000000);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }



}
